package weixin.util;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicReference;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;

import base.model.exception.BizHandleException;
import base.util.HttpRequestUtils;
import base.util.PropertiesContent;
import mt.Const;

/**
 * 提供微信接口accessToken
 * 
 * @author suan
 */
public class WxAccessTokenProvider {

	private static final Logger LOG = Logger.getLogger(WxAccessTokenProvider.class);

	private static AtomicReference<String> accessTokenRef = new AtomicReference<String>();

	private static WxAccessTokenProvider wxAccessTokenProvider;

	private WxAccessTokenProvider() {
		new Timer().schedule(new TimerTask() {
			@Override
			public void run() {
				reflushWxAccessToken();
			}
		}, 2 * 59 * 60 * 1000);
	}

	public static synchronized WxAccessTokenProvider getInstance() {
		if (wxAccessTokenProvider == null) {
			wxAccessTokenProvider = new WxAccessTokenProvider();
		}
		return wxAccessTokenProvider;
	}

	private void reflushWxAccessToken() {

		// 每次调用前清空当前 token
		accessTokenRef.set(null);

		try {

			String result = HttpRequestUtils.doGetSSL(StringUtils
					.replace(Const.WEIXIN_ACCESS_TOKEN_URL, "{appId}", PropertiesContent.get(Const.WEIXIN_APP_ID))
					.replace("{appsecret}", PropertiesContent.get(Const.WEIXIN_APP_SECRET)));
			JSONObject json = JSONObject.parseObject(result);
			Integer errorCode = 0;
			if ((errorCode = json.getInteger(Const.WEIXIN_RESP_ERRCODE_FIELD)) != null && errorCode != 0) {
				throw new BizHandleException("获取微信Token失败，返回异常！");
			}

			String accessToken = json.getString(Const.WEIXIN_RESP_ACCESS_TOKEN_FIELD);

			if (StringUtils.isNotBlank(accessToken)) {
				accessTokenRef.set(accessToken);
				LOG.info("############## reflushWxAccessToken=" + accessToken);
			}

		} catch (Exception ex) {
			LOG.error("schedule update weixin access token exception", ex);
		}
	}

	public synchronized String getAccessToken() throws BizHandleException {
		String accessToken = null;
		if ((accessToken = accessTokenRef.get()) == null) {
			reflushWxAccessToken();
			accessToken = accessTokenRef.get();
		}
		return accessToken;
	}
}
